package com.powergame.main;

import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.niftygui.NiftyJmeDisplay;
import com.jme3.scene.Node;
import com.jme3.system.AppSettings;
import com.powergame.appstates.HUD;
import com.powergame.appstates.PlayScreenState;
import com.powergame.appstates.StartScreenState;
import com.powergame.engine.PowerGameDisplayEngine;
import com.powergame.engine.PowerGameGameEngine;
import com.powergame.exceptions.PowerGameException;
import com.powergame.model.Equipe;
import com.powergame.model.Jeu;
import com.powergame.model.Joueur;
import com.powergame.model.Ordre;
import com.powergame.model.Piece;
import com.powergame.model.PiecesFactory;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.controls.Console;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * PowerGame2DMain.java
 * 
 * Classe principale pour lancer le jeu
 *
 * @author ToF
 */ 
public class PowerGame2DMain extends SimpleApplication {
    
    private static PowerGame2DMain instance = null;
    
    /** Le modele de jeu */  
    private Jeu jeu = null;
    
    /** Moteur graphique qui se charge de dessiner chaque frame */
    private PowerGameDisplayEngine displayEngine = null;
    
    private PowerGameGameEngine gameEngine = null;
    
    public BitmapText debug = null; 
    
    public boolean aquisitionPoints = false;
    
    public MapCreator mapCreator = null;
    
    public StartScreenState startState = null;
    public PlayScreenState playState = null;
    
public HUD hud = null;
    public Nifty nifty = null;
    public Console console = null;
    
    public static PowerGame2DMain getInstance(){
        return instance;
    }
    
    @Override  
    public void simpleInitApp() {
        try {
            instance = this;
            
            // Création du modele de jeu
            jeu = new Jeu();
            jeu.setPlateau(XMLPlateauLoader.loadPlateau("./assets/Maps/default.xml"));
            
            ajouteJoueur("Joueur 1", Equipe.EQUIPE_BLEU);
            ajouteJoueur("Joueur 2", Equipe.EQUIPE_ROUGE);
            
            playState = new PlayScreenState(this);
            startState  = new StartScreenState(this);
             // GUI
            initGUI();
            
            menu();
            
            //stateManager.attach(playState);
            
            // Nouveau joueur
            //ajouteJoueur(jeu, "ToF", Equipe.EQUIPE_ROUGE);
            
            // Préparation de l'affichage
            //displayEngine = new PowerGameDisplayEngine(this, settings, jeu);
            
            // Moteur du jeu
            //gameEngine = new PowerGameGameEngine(this, jeu, displayEngine);
            
            // Interface 
            //screenController = new CustomScreenController(assetManager, inputManager, audioRenderer, guiViewPort);
            
            // GUI de Débug
            /*guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
            debug = new BitmapText(guiFont, false);
            debug.setSize(guiFont.getCharSet().getRenderedSize());
            debug.setColor(ColorRGBA.Yellow);
            debug.setText("");
            debug.setLocalTranslation(0, debug.getLineHeight(), 0);
            guiNode.attachChild(debug);
            */
            //mapCreator = new MapCreator(jeu.getPlateau().getSecteurs());
        } catch (PowerGameException ex) {
            Logger.getLogger(PowerGame2DMain.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public AppSettings getSettings(){
        return settings;
    }
    
    public void initGUI(){
        NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager, getInputManager(), getAudioRenderer(), getGuiViewPort());
        nifty = niftyDisplay.getNifty();
        nifty.fromXml("Interface/gui.xml", "start", startState);
        
        Logger.getLogger("de.lessvoid.nifty").setLevel(Level.SEVERE); 
        Logger.getLogger("NiftyInputEventHandlingLog").setLevel(Level.SEVERE);
        
        getGuiViewPort().addProcessor(niftyDisplay);
        
        getInputManager().setCursorVisible(true);
        
        console = nifty.getScreen("play").findNiftyControl("console", Console.class);
        
        // Init HUD
        hud = new HUD(this);
    }
    
    public Joueur ajouteJoueur(String nom, Equipe equipe) throws PowerGameException{
        
        if(nom == null){
            throw new PowerGameException("Pas de nom");
        }
        if(equipe == null){
            throw new PowerGameException("Equipe inconnue");
        }
        
        Joueur joueur = new Joueur(jeu, nom, equipe);
        
        joueur.setFabriquePieces(new PiecesFactory(equipe, assetManager));
        
        jeu.ajouteJoueur(joueur);
        
        // Init Réserve
        joueur.addPiece(joueur.getFabriquePieces().createSoldat());
        joueur.addPiece(joueur.getFabriquePieces().createSoldat());
        joueur.addPiece(joueur.getFabriquePieces().createTank());
        joueur.addPiece(joueur.getFabriquePieces().createTank());
        joueur.addPiece(joueur.getFabriquePieces().createChasseur());
        joueur.addPiece(joueur.getFabriquePieces().createChasseur());
        joueur.addPiece(joueur.getFabriquePieces().createDestroyer());
        joueur.addPiece(joueur.getFabriquePieces().createDestroyer());
        
        return joueur;
    }
    
    public Jeu getJeu(){
        return jeu;
    }
    
    @Override
    public void simpleUpdate(float tpf) {
        //displayEngine.update(tpf);
        //gameEngine.update(tpf);
    }

    public static void main(String[] args){
        PowerGame2DMain main = new PowerGame2DMain();
        main.start();
    }
    
    public void menu(){
        nifty.gotoScreen("start");
        stateManager.attach(startState);
        startState.setEnabled(true);
        
        stateManager.detach(playState);
        playState.setEnabled(false);
    }
    
    public void play(){
        nifty.gotoScreen("play");
        stateManager.attach(playState);
        playState.setEnabled(true);
        
        stateManager.detach(startState);
        startState.setEnabled(false);
    }
    
    public void nextTour() throws PowerGameException{
        jeu.nouveauTour();
        
        updateHUD();
        
        output("Nouveau tour: " + jeu.getJoueurCourant());
    }
    
    /**
     * Ajoute une nouvelle pièce sur le plateau 
     * 
     * @param p la pièce à ajouter
     */
    public void ajoutePiece(Piece p){
        
        Node pieces = (Node)getRootNode().getChild("pieces");
        
        pieces.attachChild(p.getSpatial());
        
        updateHUD(); 
    }
    
    public void ajouteOrdre(Joueur joueur, Ordre ordre) throws PowerGameException{
        if(ordre == null){
            throw new PowerGameException("Pas d'ordre à ajouter");
        }
        
        joueur.ajouteOrdre(ordre);
        
        updateHUD();
    }
    
    public void updateHUD(){
        hud.setNomJoueur(jeu.getJoueurCourant());
        hud.setListeOrdres(jeu.getJoueurCourant().getOrdres());
        hud.setReserve(jeu.getJoueurCourant().getReserve());
    }
    
    public void output(String message){
        console.output(message);
    }
}
